package order

import (
	"parking-lot-go-admin/controller"
	"parking-lot-go-admin/model"
	"parking-lot-go-admin/model/order"
	"strconv"
	"time"

	"parking-lot-go-admin/model/park"
	"strings"

	"github.com/gin-gonic/gin"
)

// 用于接收JOIN查询结果的结构体
type OrderWithReservation struct {
	order.OrderStruct
	ParknflyStartTime  string `json:"parknfly_start_time"`
	ParknflyEndTime    string `json:"parknfly_end_time"`
	XiaoqiangStartTime string `json:"xiaoqiang_start_time"`
	XiaoqiangEndTime   string `json:"xiaoqiang_end_time"`
}

func List(c *gin.Context) {

	requestStruct := struct {
		CarNumber            *string   `json:"car_number"`
		CarNoColor           *int      `json:"car_no_color"`
		OrderType            *int      `json:"order_type"`
		ParkingLotName       *string   `json:"parking_lot_name"`
		OrderNo              *string   `json:"order_no"`
		InTime               *[]string `json:"in_time"`
		ReservationStartTime *[]string `json:"reservation_start_time"`
		ReservationEndTime   *[]string `json:"reservation_end_time"`
		Page                 int       `json:"page" binding:"required"`
		Limit                int       `json:"limit" binding:"required"`
	}{}

	if err := c.ShouldBindJSON(&requestStruct); err != nil {
		controller.Fail(c, err.Error())
		return
	}

	start := (requestStruct.Page - 1) * requestStruct.Limit

	where := " o.status=1 AND o.order_type != 0 "

	parkCodes := make([]string, 0)
	if requestStruct.ParkingLotName != nil && *requestStruct.ParkingLotName != "" {
		var parkingLotStruct park.ParkingLotStruct
		var parkingLotData []park.ParkingLotStruct
		model.GetModelData(
			model.Db,
			parkingLotStruct.TableName(),
			&parkingLotData,
			model.QueryOptions{
				Conditions: map[string]interface{}{
					"name like ?": "%%" + *requestStruct.ParkingLotName + "%%",
				},
			},
		)
		for _, v := range parkingLotData {
			parkCodes = append(parkCodes, v.ParkCode)
		}

		where += "and o.static_park_code in ("
		for _, v := range parkCodes {
			where += "'" + v + "',"
		}
		where = strings.TrimRight(where, ",")
		where += ")"
	}

	if requestStruct.CarNumber != nil && *requestStruct.CarNumber != "" {
		where += " and o.car_number like '%" + *requestStruct.CarNumber + "%'"
	}
	if requestStruct.CarNoColor != nil && *requestStruct.CarNoColor != -1 {
		where += " and o.car_no_color = " + strconv.Itoa(*requestStruct.CarNoColor)
	}
	if requestStruct.OrderType != nil && *requestStruct.OrderType != -1 {
		where += " and o.order_type = " + strconv.Itoa(*requestStruct.OrderType)
	}
	if requestStruct.OrderNo != nil && *requestStruct.OrderNo != "" {
		where += " and o.order_no like '%" + *requestStruct.OrderNo + "%'"
	}
	if requestStruct.InTime != nil && len(*requestStruct.InTime) > 0 {
		if len(*requestStruct.InTime) > 0 {
			where += " and o.in_time >= '" + (*requestStruct.InTime)[0] + "'"
		}
		if len(*requestStruct.InTime) > 1 {
			where += " and o.in_time <= '" + (*requestStruct.InTime)[1] + "'"
		}
	}

	// 构建基础WHERE条件（不包含表别名）
	baseWhere := ""
	if requestStruct.ReservationStartTime != nil && len(*requestStruct.ReservationStartTime) > 0 {
		baseWhere += " and reservation_start_time >= '" + (*requestStruct.ReservationStartTime)[0] + "'"
		if len(*requestStruct.ReservationStartTime) > 1 {
			baseWhere += " and reservation_start_time <= '" + (*requestStruct.ReservationStartTime)[1] + "'"
		}
	}
	if requestStruct.ReservationEndTime != nil && len(*requestStruct.ReservationEndTime) > 0 {
		baseWhere += " and reservation_end_time >= '" + (*requestStruct.ReservationEndTime)[0] + "'"
		if len(*requestStruct.ReservationEndTime) > 1 {
			baseWhere += " and reservation_end_time <= '" + (*requestStruct.ReservationEndTime)[1] + "'"
		}
	}

	var orderStruct order.OrderStruct

	// 构建UNION ALL查询
	joinQuery := `
		(SELECT o.*, 
		        '' as parknfly_start_time, 
		        '' as parknfly_end_time,
		        ox.reservation_start_time as xiaoqiang_start_time, 
		        ox.reservation_end_time as xiaoqiang_end_time
		FROM ` + "`" + orderStruct.TableName() + "`" + ` o
		INNER JOIN order_xiaoqiang ox ON o.order_no = ox.order_no
		WHERE ` + where + baseWhere + ` AND o.order_type = 1 and ox.reservation_end_time is not null AND ox.reservation_end_time < NOW())
		UNION ALL
		(SELECT o.*, 
		        opf.reservation_start_time as parknfly_start_time, 
		        opf.reservation_end_time as parknfly_end_time,
		        '' as xiaoqiang_start_time, 
		        '' as xiaoqiang_end_time
		FROM ` + "`" + orderStruct.TableName() + "`" + ` o
		INNER JOIN order_parknfly opf ON o.order_no = opf.order_no
		WHERE ` + where + baseWhere + ` AND o.order_type = 2 AND opf.reservation_end_time is not null AND opf.reservation_end_time < NOW())
		ORDER BY id DESC LIMIT ` + strconv.Itoa(requestStruct.Limit) + ` OFFSET ` + strconv.Itoa(start)

	//查询信息
	var orderData []OrderWithReservation
	if err := model.Db.Debug().Raw(joinQuery).Scan(&orderData).Error; err != nil {
		controller.Fail(c, err.Error())
		return
	}

	// 构建计数查询
	countQuery := `
		SELECT COUNT(*) as total FROM (
			(SELECT o.id
			FROM ` + "`" + orderStruct.TableName() + "`" + ` o
			INNER JOIN order_xiaoqiang ox ON o.order_no = ox.order_no
			WHERE ` + where + baseWhere + ` AND o.order_type = 1 AND ox.reservation_end_time is not null AND ox.reservation_end_time < NOW())
			UNION ALL
			(SELECT o.id
			FROM ` + "`" + orderStruct.TableName() + "`" + ` o
			INNER JOIN order_parknfly opf ON o.order_no = opf.order_no
			WHERE ` + where + baseWhere + ` AND o.order_type = 2 AND opf.reservation_end_time is not null AND opf.reservation_end_time < NOW())
		) as combined_orders`

	var countResult struct {
		Total int64 `json:"total"`
	}
	if err := model.Db.Debug().Raw(countQuery).Scan(&countResult).Error; err != nil {
		controller.Fail(c, err.Error())
		return
	}

	//数据格式化
	returnData := make([]map[string]interface{}, 0)
	for _, v := range orderData {

		var parkingLotStruct park.ParkingLotStruct
		if err := model.Db.Debug().Table(parkingLotStruct.TableName()).Where("park_code = ?", v.StaticParkCode).First(&parkingLotStruct).Error; err != nil {
			controller.Fail(c, err.Error())
			return
		}
		// 根据order_type获取对应的预约时间
		var reservationStartTime, reservationEndTime string
		if v.OrderType == 1 {
			// 从order_parknfly表获取时间
			reservationStartTime = v.XiaoqiangStartTime
			reservationEndTime = v.XiaoqiangEndTime
		} else if v.OrderType == 2 {
			// 从order_xiaoqiang表获取时间
			reservationStartTime = v.ParknflyStartTime
			reservationEndTime = v.ParknflyEndTime
		}

		returnData = append(returnData, map[string]interface{}{
			"static_park_code":       v.StaticParkCode,
			"parking_lot_name":       parkingLotStruct.Name,
			"car_number":             v.CarNumber,
			"car_no_color":           v.CarNoColor,
			"car_type":               v.CarType,
			"order_no":               v.OrderNo,
			"order_type":             v.OrderType,
			"in_time":                isZeroTime(v.InTime),
			"out_time":               isZeroTime(v.OutTime),
			"reservation_start_time": reservationStartTime,
			"reservation_end_time":   reservationEndTime,
			"status":                 v.Status,
		})
	}

	controller.Success(c,
		map[string]interface{}{
			"list":        returnData,
			"total":       countResult.Total,
			"pageSize":    requestStruct.Limit,
			"currentPage": requestStruct.Page,
		})

}

func isZeroTime(inTime time.Time) interface{} {
	var outTime interface{}
	if inTime.IsZero() {
		outTime = ""
	} else {
		outTime = inTime.Format("2006-01-02 15:04:05")
	}
	return outTime
}

func getTimeFromString(timeStr string) interface{} {
	if timeStr == "" {
		return ""
	}
	// 尝试解析时间字符串
	if t, err := time.Parse("2006-01-02 15:04:05", timeStr); err == nil {
		return t.Format("2006-01-02 15:04:05")
	}
	return timeStr
}
